package com.yystudy.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.yystudy.model.system.SysMenu;
import com.yystudy.model.system.SysRoleMenu;
import com.yystudy.model.vo.AssginMenuVo;
import com.yystudy.model.vo.RouterVo;
import com.yystudy.system.handler.CustomException;
import com.yystudy.system.mapper.SysMenuMapper;
import com.yystudy.system.mapper.SysRoleMenuMapper;
import com.yystudy.system.service.SysMenuService;
import com.yystudy.system.utils.MenuHelper;
import com.yystudy.system.utils.RouterHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author yystudy
 * @since 2023-10-13
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    /**
     * 菜单列表
     *
     * @return
     */
    @Override
    public List<SysMenu> findNodes() {

        //全部权限列表
        List<SysMenu> sysMenuList = this.list();
        if (CollectionUtils.isEmpty(sysMenuList)) return null;

        //构建树形数据
        List<SysMenu> result = MenuHelper.buildTree(sysMenuList);
        return result;
    }


    /**
     * 根据id删除菜单
     *
     * @param id
     */
    @Override
    public void removeMenuById(Long id) {

        LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysMenu::getParentId, id);
        Integer count = baseMapper.selectCount(lqw);

        //要删除的菜单有子菜单，不能删除
        if (count > 0) {
            throw new CustomException(201, "请先删除子菜单");
        }
        baseMapper.deleteById(id);
    }


    /**
     * 根据某个角色id获取它能操作的菜单列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<SysMenu> findSysMenuByRoleId(Long roleId) {
        //获取所有status为1的菜单权限列表
        List<SysMenu> menuList = baseMapper.selectList(
                new QueryWrapper<SysMenu>().eq("status", 1));
        //根据角色id获取角色菜单表中该角色有的所有菜单记录
        List<SysRoleMenu> roleMenus = sysRoleMenuMapper.selectList(
                new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        //获取该角色已分配的所有菜单列表id
        List<Long> roleMenuIds = new ArrayList<>();
        for (SysRoleMenu roleMenu : roleMenus) {
            roleMenuIds.add(Long.parseLong(roleMenu.getMenuId()));
        }
        //遍历所有权限列表
        for (SysMenu sysMenu : menuList) {
            //判断该角色拥有的菜单id在所有菜单id中含有多少
            if (roleMenuIds.contains(Long.parseLong(sysMenu.getId()))) {
                //设置该菜单权限已被这个角色分配
                sysMenu.setSelect(true);
            } else {
                sysMenu.setSelect(false);
            }
        }
        //将菜单权限列表转换为权限树结构返回
        List<SysMenu> sysMenus = MenuHelper.buildTree(menuList);
        return sysMenus;
    }


    /**
     * 给一个角色分配菜单列表权限
     *
     * @param assginMenuVo
     */
    @Override
    public void doAssign(AssginMenuVo assginMenuVo) {
        //删除已分配的权限
        LambdaQueryWrapper<SysRoleMenu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysRoleMenu::getRoleId,assginMenuVo.getRoleId());
        sysRoleMenuMapper.delete(lqw);
        //遍历所有已选择的权限id
        for (String menuId : assginMenuVo.getMenuIdList()) {
            if(menuId != null && menuId != ""){
                //创建SysRoleMenu对象
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setMenuId(menuId);
                sysRoleMenu.setRoleId(assginMenuVo.getRoleId());
                //将数据添加到表中
                sysRoleMenuMapper.insert(sysRoleMenu);
            }
        }
    }


    /**
     * 根据用户id，得到该用户能够操作的菜单列表
     * @param id
     * @return
     */
    @Override
    public List<RouterVo> getUserMenuList(String id) {
        //超级管理员admin账号id为：1
        List<SysMenu> sysMenuList = null;
        if ("1".equals(id)) {
            //如果是管理员账号，返回所有菜单权限
            LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SysMenu::getStatus,1);
            lqw.orderByAsc(SysMenu::getSortValue);
            sysMenuList = baseMapper.selectList(lqw);
        } else {
            //不是管理员账号，进行多表查询：用户表--->用户角色表--->角色菜单表--->菜单表
            sysMenuList = baseMapper.findListByUserId(id);
        }
        //构建树形数据
        List<SysMenu> sysMenuTreeList = MenuHelper.buildTree(sysMenuList);

        //使用树形结构构建返回的前端路由
        List<RouterVo> routerVoList = RouterHelper.buildRouters(sysMenuTreeList);
        return routerVoList;
    }


    /**
     * 根据用户id，得到该用户可以操作菜单的按钮(CURD)
     * @param id
     * @return
     */
    @Override
    public List<String> getUserButtonList(String id) {
        List<SysMenu> list = null;
        if ("1".equals(id)){
            LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SysMenu::getStatus,1);
            list = baseMapper.selectList(lqw);
        }else {
            list = baseMapper.findListByUserId(id);
        }

        if (list == null){
            return null;
        }
        ArrayList<String> permissionList = new ArrayList<>();

        for (SysMenu sysMenu : list) {
            //type为2代表是一个功能按钮
            if (sysMenu.getType() == 2) {
                //加入集合
                permissionList.add(sysMenu.getPerms());
            }
        }
        //返回按钮集合
        return permissionList;
    }
}
